package com.lkd.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.base.Strings;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lkd.entity.AbstractEntity;
import com.lkd.entity.OrderCollectEntity;
import com.lkd.entity.OrderEntity;
import com.lkd.service.OrderCollectService;
import com.lkd.service.OrderService;
import com.lkd.service.ReportService;
import com.lkd.utils.DateDay;
import com.lkd.utils.DateUtil;
import com.lkd.viewmodel.Pager;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.ShardSearchFailure;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.core.CountRequest;
import org.elasticsearch.client.core.CountResponse;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.*;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.ParsedSum;
import org.elasticsearch.search.aggregations.metrics.ValueCountAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDate;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ReportServiceImpl implements ReportService {
    @Autowired
    private OrderCollectService collectService;

    @Override
    public List<OrderCollectEntity> report(String id, Integer pageIndex, Integer pageSize, String start, String end, String nodeName) {
        LambdaQueryWrapper<OrderCollectEntity> wrapper = new LambdaQueryWrapper<>();
        LocalDate beginDateTime = LocalDate.parse(start, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        LocalDate endDateTime = LocalDate.parse(end, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        wrapper.eq(OrderCollectEntity::getOwnerId, id)
                .ge(OrderCollectEntity::getDate, beginDateTime)
                .le(OrderCollectEntity::getDate, endDateTime)
                //.groupBy(OrderCollectEntity::getOwnerName,OrderCollectEntity::getDate)
                .orderByDesc(OrderCollectEntity::getDate);

        Page<OrderCollectEntity> page = new Page<>(pageIndex, pageSize);
        Page<OrderCollectEntity> entityPage = collectService.page(page, wrapper);
        return entityPage.getRecords();
    }

    //数据导出
    @Autowired
    private OrderCollectService orderCollectService;
    //数据导出
    @Autowired
    private OrderService orderService;

    @Override
    public List<OrderCollectEntity> getList(Integer partnerId, String nodeName, LocalDate start, LocalDate end) {
        var qw = new LambdaQueryWrapper<OrderCollectEntity>();
        qw
                .eq(OrderCollectEntity::getOwnerId, partnerId)
                .ge(OrderCollectEntity::getDate, start)
                .le(OrderCollectEntity::getDate, end);

        if (!Strings.isNullOrEmpty(nodeName)) {
            qw.like(OrderCollectEntity::getNodeName, nodeName);
        }


        return orderCollectService.list(qw);
    }

    @Override
    public Map amountCollect(String start, String end) {
        List<LocalDate> dateDay = DateDay.getDateDay(start, end);
        ArrayList<Integer> num = new ArrayList<>();
        for (LocalDate xAxi : dateDay) {
            Integer money=0;
            List<OrderEntity> orderEntityList = orderService.list(Wrappers.<OrderEntity>lambdaQuery()
                    .le(AbstractEntity::getCreateTime, xAxi.plusDays(1))
                    .ge(AbstractEntity::getCreateTime, xAxi)
            );
            for (OrderEntity orderEntity : orderEntityList) {
                money+=orderEntity.getAmount();
            }
            num.add(money);
        }
        Map<Object, Object> map = new HashMap<>();
        map.put("xAxis", dateDay);
        map.put("series", num);
        return map;
    }

    @Autowired
    private RestHighLevelClient esClient;

    @Override
    public Map regionCollect(String start, String end) {

        LocalDate startTime = LocalDate.parse(start, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        LocalDate endTime = LocalDate.parse(end, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        ArrayList<Double> num = new ArrayList<>();
        ArrayList<String> name = new ArrayList<>();

        AggregationBuilder aggregationBuilder = AggregationBuilders
                .terms("region")
                .field("region_name")
                .subAggregation(AggregationBuilders.sum("amount_sum").field("amount"))
                .order(BucketOrder.aggregation("amount_sum", false))
                .size(30);
        SearchRequest searchRequest = new SearchRequest("order");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("create_time").lte(endTime).gte(startTime);
        searchSourceBuilder.aggregation(aggregationBuilder);
        searchSourceBuilder.query(rangeQueryBuilder);
        searchRequest.source(searchSourceBuilder);
        try {
            SearchResponse response = esClient.search(searchRequest, RequestOptions.DEFAULT);
            Aggregations aggregation = response.getAggregations();
            var term = (ParsedStringTerms) aggregation.get("region");
            term.getBuckets().stream().forEach(
                    e -> {
                        String keyAsString = e.getKeyAsString();
                        ParsedSum amount_sum = (ParsedSum) e.getAggregations().get("amount_sum");
                        double value = amount_sum.getValue();
                        name.add(keyAsString);
                        num.add(value);
                    }
            );

        } catch (IOException e) {
            e.printStackTrace();
        }
        Map<Object, Object> map = new HashMap<>();
        map.put("xAxis", name);
        map.put("series", num);
        return map;

        //map.put("xAxis",date);
/*        ArrayList<Object> num = new ArrayList<>();
        for (LocalDate xAxi : dateDay) {
            QueryBuilders.
        }*/
//        return null;
    }

    /**
     * 合作商点位分账查询
     *
     * @param ownerId
     * @return
     */
    @Override
    public List<OrderCollectEntity> top12Collect(String ownerId) {
        LambdaQueryWrapper<OrderCollectEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(OrderCollectEntity::getOwnerId, ownerId)
                .orderByDesc(OrderCollectEntity::getDate);
        return collectService.list(queryWrapper);
    }

    /*  */

    /**
     * 收益统计趋势
     *
     * @param partnerId
     * @param start
     * @param end
     * @return
     */
    public static void main(String[] args) {
        LocalDate startTime = LocalDate.parse("2022-05-01", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        LocalDate endTime = LocalDate.parse("2021-05-01", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        System.out.println(startTime.toEpochDay() - endTime.toEpochDay());

        System.out.println(startTime.equals(endTime));


    }

    @Override
    public Map<String, List> collectReport(String partnerId, String start, String end) {
        LocalDate startTime = LocalDate.parse(start, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        LocalDate endTime = LocalDate.parse(end, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        LocalDate newstart = null;
        LocalDate newend;
        ArrayList<Object> date = new ArrayList<>();
        ArrayList<Object> money = new ArrayList<>();
        for (long i = 0; i < (endTime.toEpochDay() - startTime.toEpochDay()) + 1; i++) {
            if (i == 0) newstart = startTime;
            newend = startTime.plusDays(i + 1);
            List<OrderCollectEntity> list = collectService.list(Wrappers.<OrderCollectEntity>lambdaQuery()
                    .eq(OrderCollectEntity::getOwnerId, partnerId).le(OrderCollectEntity::getDate, newend)
                    .ge(OrderCollectEntity::getDate, newstart));
            Integer money2 = 0;
            for (OrderCollectEntity orderCollectEntity : list) {
                money2 += orderCollectEntity.getTotalBill();
            }
            date.add(newstart);
            money.add(money2);
            newstart = newend;
        }
        HashMap<String, List> map = new HashMap<>();
        map.put("xAxis", date);
        map.put("series", money);
        return map;
    }



}
